package com.eshore.textanalyzer.elk.common;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;

/**
 * @author xyd
 * @date 2021/5/12
 */
@Component
public class ESRestClient {
    private static final Logger logger = LoggerFactory.getLogger(ESRestClient.class);

    @Autowired
    private ElasticConf elasticConf;

    private static ESRestClient restClientUtil;

    private static RestHighLevelClient client = null;

    @PostConstruct
    public void init() {
        restClientUtil = this;
        restClientUtil.elasticConf = this.elasticConf;
    }

    /**
     * 获取高级api客户端
     */
    public RestHighLevelClient getClient() {
        if (client != null) {
            return client;
        } else {
            synchronized (ESRestClient.class) {
                String hostName = restClientUtil.elasticConf.getHost();
                String port = restClientUtil.elasticConf.getPort();
                String userName = restClientUtil.elasticConf.getUsername();
                String password = restClientUtil.elasticConf.getPassword();
                String[] hosts = hostName.split(",");
                HttpHost[] httpHosts = new HttpHost[hosts.length];
                HttpHost httpHost = null;
                for (int i = 0; i < hosts.length; i++) {
                    if (hosts[i].contains(":")) {
                        String h = hosts[i].split(":")[0];
                        String p = hosts[i].split(":")[1];
                        httpHost = new HttpHost(h, Integer.parseInt(p));
                    } else {
                        httpHost = new HttpHost(hosts[i], Integer.parseInt(port));
                    }
                    httpHosts[i] = httpHost;
                }
                boolean flag = ((userName == null) || userName.isEmpty()) && ((password == null) || password.isEmpty());
                if (flag) {
                    client = new RestHighLevelClient(RestClient.builder(httpHosts));
                } else {
                    BasicCredentialsProvider provider = new BasicCredentialsProvider();
                    provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));

                    client = new RestHighLevelClient(
                            RestClient.builder(httpHosts).setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
                                @Override
                                public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder builder) {
                                    return builder.setConnectTimeout(5000 * 1000) // 连接超时（默认为1秒）
                                            .setSocketTimeout(6000 * 1000); // 套接字超时（默认为30秒）//更改客户端的超时限制默认30秒现在改为100*1000分钟
                                }
                            }).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                                @Override
                                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
                                    httpAsyncClientBuilder.disableAuthCaching();
                                    return httpAsyncClientBuilder.setDefaultCredentialsProvider(provider);
                                }
                            })
                    ); // 调整最大重试超时时间（默认为30秒）.setMaxRetryTimeoutMillis(60000);
                }
                return client;
            }
        }
    }

    /**
     * 关闭客户端
     */
    public void closeClient() {
        if (client != null) {
            try {
                client.close();
            } catch (IOException e) {
                logger.error("#--#RestHighLevelClient Close failure !!!");
                e.printStackTrace();
            }
            client = null;
        }
    }
}
